home *** CD-ROM | disk | FTP | other *** search
/ PC World Komputer 2010 April / PCWorld0410.iso / hity wydania / Ubuntu 9.10 PL / karmelkowy-koliberek-desktop-9.10-i386-PL.iso / casper / filesystem.squashfs / usr / bin / dpkg-statoverride < prev    next >
Text File  |  2009-09-20  |  6KB  |  248 lines

  1. #! /usr/bin/perl
  2.  
  3. BEGIN { # Work-around for bug #479711 in perl
  4.     $ENV{PERL_DL_NONLAZY} = 1;
  5. }
  6.  
  7. use strict;
  8. use warnings;
  9.  
  10. use POSIX;
  11. use POSIX qw(:errno_h :signal_h);
  12. use Dpkg;
  13. use Dpkg::Gettext;
  14.  
  15. textdomain("dpkg");
  16.  
  17. my $verbose = 1;
  18. my $doforce = 0;
  19. my $doupdate = 0;
  20. my $mode = "";
  21.  
  22. my %owner;
  23. my %group;
  24. my %mode;
  25.  
  26. sub version {
  27.     printf _g("Debian %s version %s.\n"), $progname, $version;
  28.  
  29.     printf _g("
  30. Copyright (C) 2000 Wichert Akkerman.");
  31.  
  32.     printf _g("
  33. This is free software; see the GNU General Public Licence version 2 or
  34. later for copying conditions. There is NO warranty.
  35. ");
  36. }
  37.  
  38. sub usage {
  39.     printf _g(
  40. "Usage: %s [<option> ...] <command>
  41.  
  42. Commands:
  43.   --add <owner> <group> <mode> <file>
  44.                            add a new entry into the database.
  45.   --remove <file>          remove file from the database.
  46.   --list [<glob-pattern>]  list current overrides in the database.
  47.  
  48. Options:
  49.   --admindir <directory>   set the directory with the statoverride file.
  50.   --update                 immediately update file permissions.
  51.   --force                  force an action even if a sanity check fails.
  52.   --quiet                  quiet operation, minimal output.
  53.   --help                   show this help message.
  54.   --version                show the version.
  55. "), $progname;
  56. }
  57.  
  58. sub CheckModeConflict {
  59.     return unless $mode;
  60.     badusage(sprintf(_g("two commands specified: %s and --%s"), $_, $mode));
  61. }
  62.  
  63. while (@ARGV) {
  64.     $_=shift(@ARGV);
  65.     last if m/^--$/;
  66.     if (!m/^-/) {
  67.         unshift(@ARGV,$_); last;
  68.     } elsif (m/^--help$/) {
  69.         usage();
  70.         exit(0);
  71.     } elsif (m/^--version$/) {
  72.         version();
  73.         exit(0);
  74.     } elsif (m/^--update$/) {
  75.         $doupdate=1;
  76.     } elsif (m/^--quiet$/) {
  77.         $verbose=0;
  78.     } elsif (m/^--force$/) {
  79.         $doforce=1;
  80.     } elsif (m/^--admindir$/) {
  81.         @ARGV || badusage(sprintf(_g("--%s needs a <directory> argument"), "admindir"));
  82.         $admindir= shift(@ARGV);
  83.     } elsif (m/^--add$/) {
  84.         CheckModeConflict();
  85.         $mode= 'add';
  86.     } elsif (m/^--remove$/) {
  87.         CheckModeConflict();
  88.         $mode= 'remove';
  89.     } elsif (m/^--list$/) {
  90.         CheckModeConflict();
  91.         $mode= 'list';
  92.     } else {
  93.         badusage(sprintf(_g("unknown option \`%s'"), $_));
  94.     }
  95. }
  96.  
  97. my $dowrite = 0;
  98. my $exitcode = 0;
  99.  
  100. badusage(_g("no mode specified")) unless $mode;
  101. ReadOverrides();
  102.  
  103. if ($mode eq "add") {
  104.     @ARGV == 4 || badusage(_g("--add needs four arguments"));
  105.  
  106.     my $user = $ARGV[0];
  107.     my $uid = 0;
  108.     my $gid = 0;
  109.  
  110.     if ($user =~ m/^#([0-9]+)$/) {
  111.         $uid=$1;
  112.         badusage(sprintf(_g("illegal user %s"), $user)) if ($uid < 0);
  113.     } else {
  114.         my ($name, $pw);
  115.         (($name, $pw, $uid) = getpwnam($user)) ||
  116.             badusage(sprintf(_g("non-existing user %s"), $user));
  117.     }
  118.  
  119.     my $group = $ARGV[1];
  120.     if ($group =~ m/^#([0-9]+)$/) {
  121.         $gid=$1;
  122.         badusage(sprintf(_g("illegal group %s"), $group)) if ($gid < 0);
  123.     } else {
  124.         my ($name, $pw);
  125.         (($name, $pw, $gid) = getgrnam($group)) ||
  126.             badusage(sprintf(_g("non-existing group %s"), $group));
  127.     }
  128.  
  129.     my $mode = $ARGV[2];
  130.     (($mode < 0) or (oct($mode) > 07777) or ($mode !~ m/\d+/)) &&
  131.         badusage(sprintf(_g("illegal mode %s"), $mode));
  132.     my $file = $ARGV[3];
  133.     $file =~ m/\n/ && badusage(_g("file may not contain newlines"));
  134.     $file =~ s,/+$,, && print STDERR _g("stripping trailing /")."\n";
  135.  
  136.     if (defined $owner{$file}) {
  137.         printf STDERR _g("An override for \"%s\" already exists, "), $file;
  138.         if ($doforce) {
  139.             print STDERR _g("but --force specified so will be ignored.")."\n";
  140.         } else {
  141.             print STDERR _g("aborting")."\n";
  142.             exit(3);
  143.         }
  144.     }
  145.     $owner{$file}=$user;
  146.     $group{$file}=$group;
  147.     $mode{$file}=$mode;
  148.     $dowrite=1;
  149.  
  150.     if ($doupdate) {
  151.         if (not -e $file) {
  152.         printf STDERR _g("warning: --update given but %s does not exist")."\n", $file;
  153.         } else {
  154.         chown ($uid,$gid,$file) || warn sprintf(_g("failed to chown %s: %s"), $file, $!)."\n";
  155.         chmod (oct($mode),$file) || warn sprintf(_g("failed to chmod %s: %s"), $file, $!)."\n";
  156.         }
  157.     }
  158. } elsif ($mode eq "remove") {
  159.     @ARGV == 1 || badusage(sprintf(_g("--%s needs a single argument"), "remove"));
  160.     my $file = $ARGV[0];
  161.     $file =~ s,/+$,, && print STDERR _g("stripping trailing /")."\n";
  162.     if (not defined $owner{$file}) {
  163.         print STDERR _g("No override present.")."\n";
  164.         exit(0) if ($doforce); 
  165.         exit(2);
  166.     }
  167.     delete $owner{$file};
  168.     delete $group{$file};
  169.     delete $mode{$file};
  170.     $dowrite=1;
  171.     print(STDERR _g("warning: --update is useless for --remove")."\n") if ($doupdate);
  172. } elsif ($mode eq "list") {
  173.     my (@list, @ilist);
  174.  
  175.     @ilist= @ARGV ? @ARGV : ('*');
  176.     while (defined($_=shift(@ilist))) {
  177.         s/\W/\\$&/g;
  178.         s/\\\?/./g;
  179.         s/\\\*/.*/g;
  180.         s,/+$,, && print STDERR _g("stripping trailing /")."\n";
  181.         push(@list,"^$_\$");
  182.     }
  183.  
  184.     my $pattern = join('|', @list);
  185.     $exitcode=1;
  186.     for my $file (keys %owner) {
  187.         next unless ($file =~ m/$pattern/o);
  188.         $exitcode=0;
  189.         print "$owner{$file} $group{$file} $mode{$file} $file\n";
  190.     }
  191. }
  192.  
  193. WriteOverrides() if ($dowrite);
  194.  
  195. exit($exitcode);
  196.  
  197. sub ReadOverrides {
  198.     open(SO, "$admindir/statoverride") ||
  199.         quit(sprintf(_g("cannot open statoverride: %s"), $!));
  200.     while (<SO>) {
  201.         my ($owner,$group,$mode,$file);
  202.         chomp;
  203.  
  204.         ($owner,$group,$mode,$file)=split(' ', $_, 4);
  205.         die sprintf(_g("Multiple overrides for \"%s\", aborting"), $file)
  206.             if defined $owner{$file};
  207.         $owner{$file}=$owner;
  208.         $group{$file}=$group;
  209.         $mode{$file}=$mode;
  210.     }
  211.     close(SO);
  212. }
  213.  
  214.  
  215. sub WriteOverrides {
  216.     my ($file);
  217.  
  218.     open(SO, ">$admindir/statoverride-new") ||
  219.         quit(sprintf(_g("cannot open new statoverride file: %s"), $!));
  220.     foreach $file (keys %owner) {
  221.         print SO "$owner{$file} $group{$file} $mode{$file} $file\n";
  222.     }
  223.     close(SO);
  224.     chmod(0644, "$admindir/statoverride-new");
  225.     unlink("$admindir/statoverride-old") ||
  226.         $! == ENOENT || quit(sprintf(_g("error removing statoverride-old: %s"), $!));
  227.     link("$admindir/statoverride","$admindir/statoverride-old") ||
  228.         $! == ENOENT || quit(sprintf(_g("error creating new statoverride-old: %s"), $!));
  229.     rename("$admindir/statoverride-new","$admindir/statoverride")
  230.         || quit(sprintf(_g("error installing new statoverride: %s"), $!));
  231. }
  232.  
  233.  
  234. sub quit
  235. {
  236.     printf STDERR "%s: %s\n", $0, "@_";
  237.     exit(2);
  238. }
  239.  
  240. sub badusage
  241. {
  242.     printf STDERR "%s: %s\n\n", $0, "@_";
  243.     usage();
  244.     exit(2);
  245. }
  246.  
  247. # vi: ts=8 sw=8 ai si cindent
  248.